<template>
  <div class="gallery-list" @mouseenter="isHover = true" @mouseleave="isHover = false">
    <div class="gallery-container gallery-timeline container-content" :style="{backgroundColor: modelValue?.bgColor}">
      <div class="gallery-timeline">
        <div class="gallery-timeline__list">
          <ScrollBar :hideScrollbar="innerWidth < 768" ref="scroller">
            <div class="list__wrapper">
              <ul class="timeline__list">
                <li
                  class="timeline__item"
                  v-for="timelineItem in modelValue?.data"
                  :key="timelineItem.id"
                  :ref="(el: HTMLElement) => { if (el) item.push(el as HTMLElement) }"
                >
                  <div class="item__line" :ref="(el: HTMLElement) => { if (el) line.push(el as HTMLElement) }">
                    <div class="item__line__mobile"></div>
                    <div class="item__dot"></div>
                  </div>
                  <div
                    class="d-flex flex-column flex-md-row justify-content-between"
                    :class="{ 'has-date': !!timelineItem.date }"
                  >
                    <div>
                      <h6
                        v-if="!timelineItem.date"
                        v-show="timelineItem.title"
                        class="text-blue-dark"
                        v-html="timelineItem.title"
                      ></h6>
                      <h4
                        v-else
                        v-show="timelineItem.title"
                        class="text-blue-dark"
                        v-html="timelineItem.title"
                      ></h4>
                      <div
                        v-show="timelineItem.date"
                        class="tx-body-big text-blue-dark mb-3 mb-md-5 pe-3"
                        v-html="timelineItem.date"
                      ></div>
                      <div
                        v-show="timelineItem.text"
                        class="tx-body-p text-teal-darkest mb-3 mb-md-5 pe-3"
                        v-html="timelineItem.text"
                      ></div>
                      <div
                        v-if="timelineItem.url"
                        class="my-3 my-md-5 pe-4"
                      >
                        <a
                          :href="timelineItem.url"
                          target="_blank"
                          class="timeline__item__button d-inline-block"
                        >
                          <div
                            class="timeline__item__button__text"
                          >
                            {{ timelineItem.btnText }}
                          </div>
                        </a>
                      </div>
                    </div>
                    <a-image
                      v-if="timelineItem.imgSrc"
                      class="flex-shrink-0 img-fit mb-8 mb-md-0 ms-md-15 mt-md-2 pe-4 cursor-pointer w-md-30"
                      :src="timelineItem.imgSrc"
                      :alt="timelineItem.alt"
                      :preview="true"
                     />
                  </div>
                </li>
              </ul>
              <div
                v-if="showLoadMoreBtn"
                class="d-flex justify-content-center mt-6"
              >
                <button
                  type="button"
                  class="btn btn__load-more"
                  @click="showNum += addNum"
                >
                  <div class="btn--udrline">
                    更多
                  </div>
                  <span class="i i-load-more"></span>
                </button>
              </div>
            </div>
          </ScrollBar>
        </div>
      </div>
    </div>

     <Operate v-if="!isPreview" v-model:show="isHover" @handle-edit="showSetting = true" @handle-delete="handleDelete" @handle-copy="handleCopy" @handle-paste="handlePaste"></Operate>
  </div>

  <Setting v-if="!isPreview" v-model:show="showSetting" :data="modelValue"></Setting>
</template>

<script lang="ts" setup>
import { computed, ref, watch, nextTick, onMounted } from 'vue'
import { randomString } from '@/utils/common'
import Setting from './setting.vue'
import Operate from '@/common/Operate/index.vue'
import ScrollBar from '@/common/ScrollBar/index.vue'
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'

// 注册 GSAP 插件（SSR 安全）
if (typeof window !== 'undefined') {
  try {
    gsap.registerPlugin(ScrollTrigger)
  } catch (e) {
    // ignore
  }
}

// 定义组件名称
defineOptions({
  name: 'GalleryTimeline'
})

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => {}
  },

  // 是否预览
  isPreview: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['update:modelValue', 'handleDelete', 'handleCopy', 'handlePaste'])

const innerWidth = computed(() => {
  return (typeof window === 'undefined' ? 1024 : window.innerWidth)
})

const handleInit = () => {
  if (props.modelValue && props.modelValue.data) return // 有数据不用初始化
  const data = {
    id: props.modelValue?.id || randomString(),
    type: 'GalleryTimeline',
    bgColor: '',
    data: [
      {
        id: randomString(),
        title: '标题',
        text: '内容',
        date: '1990',
        imgSrc: 'https://osswebsite-test.cedim.cn/media-library/ywies-bj/images/home/ywies-tx.jpg',
        alt: '',
        url: 'http://baidu.com',
        btnText: '按钮',
      },
      {
        id: randomString(),
        title: '标题',
        text: '内容',
        date: '1990',
        imgSrc: 'https://osswebsite-test.cedim.cn/media-library/ywies-bj/images/home/ywies-tx.jpg',
        alt: '',
        url: 'http://baidu.com',
        btnText: '按钮',
      },
    ]
  }
  emit('update:modelValue', data)
} 

const isHover = ref<boolean>(false);
const showSetting = ref<boolean>(false);

const handleDelete = () => {
  emit('handleDelete', props.modelValue.id)
}

const handleCopy = () => {
  emit('handleCopy', props.modelValue)
}

const handlePaste = (type: string) => {
  emit('handlePaste', type)
}

handleInit()

// 动画相关变量
let tl: any = null;
const showNum = ref<number>(5);
const addNum = ref<number>(5);
let waitTimestamp: number | null = null;

const list = computed(() => {
  return props.modelValue?.data ?? null
})
const sliceList = computed(() => {
  if (innerWidth.value >= 768) return list.value;
  return list.value?.slice(0, showNum.value);
})
const showLoadMoreBtn = computed(() => {
  return innerWidth.value <= 767.98 && showNum.value < list.value?.length;
})
const getScreenScrollY = () => {
  if (typeof window !== 'undefined')
    return Math.round(window.pageYOffset);
  return 0
}
const vsScrollY = computed(() => {
  return getScreenScrollY();
})
watch(() => vsScrollY.value, () => {
  if (innerWidth.value >= 768) return;
    throttle(forceUpdateTl, 5000);
})

watch(() => sliceList.value, () => {
  forceUpdateTl()
})

// 模板引用
const line = ref<HTMLElement[]>([])
const item = ref<HTMLElement[]>([])
const scroller = ref<any>(null)

// 方法定义
const forceUpdateTl = () => {
  tl = null
  nextTick(animateOnScroll)
}

const animateOnScroll = () => {
  tl = gsap.timeline()
  const lines = line.value
  const items = item.value
  const scrollerEl = scroller.value?.$el?.querySelector(".simplebar-content-wrapper")

  if (!lines || !items) return

  lines.forEach((lineEl: HTMLElement, idx: number) => {
    tl.fromTo(
      lineEl,
      {
        "--line-height": "0%",
      },
      {
        "--line-height": "100%",
        scrollTrigger: {
          start: () => {
            if ((typeof window === 'undefined' ? 1024 : window.innerWidth) < 768) {
              return "top center"
            } else {
              const top = 50 + idx * 35
              return `top top+=${top}px`
            }
          },
          end: () => {
            if ((typeof window === 'undefined' ? 1024 : window.innerWidth) < 768) {
              return "center center"
            } else {
              const bottom = idx * 25
              return `bottom center+=${bottom}px`
            }
          },
          scrub: 1,
          trigger: items[idx],
          scroller: scrollerEl,
          onEnter: (self: any) => {
            self.trigger.classList.add("is-enter")
          },
          onEnterBack: (self: any) => {
            self.trigger.classList.remove("is-enter")
          },
          onLeaveBack: (self: any) => {
            self.trigger.classList.remove("is-enter")
          },
        },
      }
    )
  })
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const throttle = (callback: () => void, delay: number) => {
  if (waitTimestamp) {
    if (waitTimestamp + delay < Date.now()) {
      callback()
      waitTimestamp = Date.now()
    }
  } else {
    callback()
    waitTimestamp = Date.now()
  }
}

// 组件挂载后执行
onMounted(() => {
  nextTick(animateOnScroll)
})
</script>

<style lang="scss" scoped>
.gallery-list {
  position: relative;
  width: 100%;
}

.gallery-list {
  // class="arco-image arco-image-with-footer-inner flex-shrink-0 img-fit mb-8 mb-md-0 ms-md-15 mt-md-2 pe-4 cursor-pointer w-md-30"
  .d-flex {
    display: flex !important;
  }

  .flex-column {
    flex-direction: column !important;
  }

  @media(min-width: 768px) {
    .flex-md-row {
      flex-direction: row !important;
    }
  }

  .justify-content-between {
    justify-content: space-between !important;
  }

  .justify-content-center {
    justify-content: center !important;
  }

  .text-blue-dark {
    --bs-text-opacity: 1;
    color: rgba(0,50,160,var(--bs-text-opacity))!important;
  }

  .tx-body-big {
    font-size: 16px;
    font-weight: 500;
    line-height: 1.5;
    letter-spacing: .01em
  }

  @media(max-width: 1023.98px) {
    .tx-body-big {
        line-height:1.25;
        letter-spacing: .04em
    }
  }

  @media(max-width: 767.98px) {
    .tx-body-big {
        font-size:14px;
        line-height: 1.285;
        letter-spacing: .02em
    }
  }

  .mb-3 {
    margin-bottom: 12px!important
  }
  .mb-8 {
    margin-bottom: 32px!important
  }
  .mb-md-5 {
    @media(min-width: 768px) {
      margin-bottom: 20px!important
    }
  }
  .mb-md-0 {
    @media(min-width: 768px) {
      margin-bottom: 0!important
    }
  }
  .mt-6 {
    margin-top: 24px!important
  }
  .my-3 {
    margin-top: 12px!important;
    margin-bottom: 12px!important
  }
  .pe-3 {
    padding-right: 12px!important
  }
  .pe-4 {
    padding-right: 16px!important
  }
  .ms-md-15 {
    @media(min-width: 768px) {
      margin-left: 60px!important
    }
  }
  .mt-md-2 {
    @media(min-width: 768px) {
      margin-top: 8px!important
    }
  }
  .w-md-30 {
    @media(min-width: 768px) {
      width: 30%!important
    }
  }

  .d-inline-block {
    display: inline-block!important
  }

  .flex-shrink-0 {
    flex-shrink: 0!important
  }

  .btn {
    display: flex;
    align-items: center;
    justify-content: center;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    background-color: transparent;
    cursor: pointer;
    position: relative;
    text-decoration: none;
    border: none;
    outline: none;
    color: #0048e8;
    color: var(--text-color,#0048e8)
  }

  .btn.btn__load-more {
    --text-color: #0032a0
  }

  .btn--udrline {
    display: flex;
    flex-direction: column
  }

  .btn--udrline--active:after,.btn--udrline:hover:after {
    transform: scaleX(1)
  }

  .btn--udrline:after {
    content: "";
    width: 100%;
    height: 1px;
    border-radius: 1px;
    background-color: #0048e8;
    background-color: var(--text-color,#0048e8);
    transform: scaleX(0);
    transition: all .3s ease-in-out
  }

  .btn--active,.btn:hover {
    color: #0048e8;
    color: var(--text-color,#0048e8)
  }

  .btn--active .btn--udrline:after,.btn:hover .btn--udrline:after {
    transform: scaleX(1)
  }

  i {
    position: relative
  }

  .i:after,.i:before {
    content: "";
    display: inline-block;
    vertical-align: middle
  }

  .i-load-more:before {
    transition: all .2s ease-in-out;
    width: 16px;
    height: 16px;
    margin-left: 4px
  }

  @media(prefers-reduced-motion:reduce) {
    .i-load-more:before {
        transition: none
    }
  }

  .i-load-more:before {
    background: url() 50% no-repeat;
    background-size: 100% auto
  }
}

.gallery-timeline {
  display: flex;
  flex: 1;
}

@media(max-width: 767.98px) {
  .gallery-timeline {
    flex-direction: column-reverse;
  }
}

.gallery-timeline__list {
  width: 346px;
  padding: 12px 12px 0;
}

.gallery-timeline__list:only-child {
  width: 100%;
}

@media(max-width: 767.98px) {
  .gallery-timeline__list {
    width:100%;
    padding: 0 12px 24px;
  }
}

@media(min-width: 768px) {
  .gallery-timeline__list>.scroll-bar .simple-bar {
    max-height: 428px;
  }
}

.gallery-timeline__list .list__wrapper .timeline__list {
  padding-top: 28px;
  padding-bottom: 100px;
}

@media(max-width: 767.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list {
    padding-top: 20px;
    padding-bottom: 0;
  }
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item {
  display: flex;
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line {
  position: relative;
  margin-right: 32px;
  margin-left: 12px;
  transform: translateY(4px);
}

@media(max-width: 767.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line {
    margin-right:20px;
    margin-left: 6px;
  }
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line__mobile {
  position: absolute;
  left: 0;
  top: 0;
  height: 0%;
  height: var(--line-height,0%);
  width: 1px;
  background-image: linear-gradient(180deg,transparent,transparent 50%,#f7f7fa 0,#f7f7fa),linear-gradient(180deg,#0032a0,#0032a0);
  background-size: 20px 5px,100% 5px;
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line:after,.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line:before {
  height: 100%;
  border-left: 1px solid rgba(26,28,32,.2);
}

@media(max-width: 767.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line:before {
    border-left:none;
    width: 1px;
    background-image: linear-gradient(180deg,transparent,transparent 50%,#f7f7fa 0,#f7f7fa),linear-gradient(180deg,rgba(26,28,32,.2),rgba(26,28,32,.2));
    background-size: 20px 5px,100% 5px;
  }
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line:after {
  height: 0%;
  height: var(--line-height,0%);
  border-left: 1px solid #0032a0;
  transition: max-height .4s ease-in-out;
}

@media(max-width: 767.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line:after {
    border-left: none;
  }
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line .item__dot {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 0;
  height: 16px;
  width: 16px;
  background-color: #f7f7fa;
  border: 6px solid #c0c0c4;
  border-radius: 50%;
  transform: translateX(-50%);
  transition: border-color .15s;
}

@media(max-width: 767.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item .item__line .item__dot {
    height:8px;
    width: 8px;
    background-color: #c0c0c4;
    border: none;
    transform: translateX(-45%);
  }
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item.is-enter .item__line .item__dot,.gallery-timeline__list .list__wrapper .timeline__list .timeline__item:first-child .item__line .item__dot {
  border: 6px solid #0032a0;
}

@media(max-width: 767.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item.is-enter .item__line .item__dot,.gallery-timeline__list .list__wrapper .timeline__list .timeline__item:first-child .item__line .item__dot {
    background-color:#0032a0;
    border: none;
  }
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item:not(.is-enter) .item__line__mobile {
  height: 0;
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item:last-of-type .item__line:after,.gallery-timeline__list .list__wrapper .timeline__list .timeline__item:last-of-type .item__line:before,.gallery-timeline__list .list__wrapper .timeline__list .timeline__item:last-of-type .item__line__mobile {
  opacity: 0;
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item .cursor-pointer {
  cursor: pointer;
}

@media(min-width: 768px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item .has-date {
    margin-top:-16px;
    padding-bottom: 48px;
  }
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item__button {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background-color: #0032a0;
  background-color: var(--text-color--primary,#0032a0);
  padding: 11px 15px;
  min-width: 160px;
  border: none;
  border-radius: 4px;
  overflow: hidden;
  text-decoration: none;
  box-shadow: 0 2px 6px rgba(130,130,140,.12);
  position: relative;
  z-index: 1;
  white-space: nowrap;
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item__button:before {
  content: "";
  display: block;
  background: #0048e8;
  position: absolute;
  width: 200%;
  height: 500%;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
  transition: all .3s ease-in-out;
  z-index: -1;
  -webkit-clip-path: circle(100% at -80% 90%);
  clip-path: circle(100% at -80% 90%);
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item__button:hover:before {
  -webkit-clip-path: circle(100% at 50% 50%);
  clip-path: circle(100% at 50% 50%);
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item__button:active:before {
  -webkit-clip-path: circle(100% at -80% 90%);
  clip-path: circle(100% at -80% 90%);
}

.gallery-timeline__list .list__wrapper .timeline__list .timeline__item__button__text {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.285;
  letter-spacing: .04em;
  color: #fff;
  transition: color .3s ease-in-out;
}

@media(max-width: 1023.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item__button__text {
    line-height: 1.428;
  }
}

@media(max-width: 767.98px) {
  .gallery-timeline__list .list__wrapper .timeline__list .timeline__item__button__text {
    line-height: 1.285;
  }
}

.gallery-timeline__gallery {
  flex: 1 1 auto;
  margin-left: 12px;
}

@media(max-width: 767.98px) {
  .gallery-timeline__gallery {
    margin-left: 0;
  }
}

.gallery-timeline__gallery .row {
  --bs-gutter-x: 12px;
  --bs-gutter-y: 12px;
}

@media(max-width: 767.98px) {
  .gallery-timeline__gallery .row {
    --bs-gutter-x: 4px;
    --bs-gutter-y: 4px;
  }
}

.gallery-timeline__gallery .img-wrapper {
  padding-bottom: 73.79%;
  cursor: pointer;
}

.img-fit {
  width: 100%;
  height: auto !important;
  object-fit: contain;
}

:deep(.arco-image-img) {
  width: 100%;
  height: auto;
}
</style>